using System;

public static class EnumTools {
	// === Public =====================================================================================================
	#region Values
	public static Array GetValues<T>() where T : struct, IConvertible {
		return GetValues(typeof(T));
	}

	public static Array GetValues(Type enumType) {
		if (!enumType.IsEnum) {
			throw new ArgumentException("T must be an enumerated type");
		}
		return Enum.GetValues(enumType);
	}
	#endregion

	#region Names
	public static string[] GetNames<T>() where T : struct, IConvertible {
		return GetNames(typeof(T));
	}

	public static string[] GetNames(Type enumType) {
		if (!enumType.IsEnum) {
			throw new ArgumentException("T must be an enumerated type");
		}
		return Enum.GetNames(enumType);
	}
	#endregion

	#region Parse from string
	public static T Parse<T>(string value) where T : struct, IConvertible {
		return (T)Parse(typeof(T), value);
	}

	public static object Parse(Type enumType, string value) {
		if (!enumType.IsEnum) {
			throw new ArgumentException("T must be an enumerated type");
		}
		if (string.IsNullOrEmpty(value)) {
			throw new ArgumentException("Value is null or empty");
		}
		return Enum.Parse(enumType, value);
	}
	#endregion

	#region Parse from int
	public static T Parse<T>(int value) where T : struct, IConvertible {
		return (T)Parse(typeof(T), value);
	}

	public static object Parse(Type enumType, int value) {
		if (!enumType.IsEnum) {
			throw new ArgumentException("T must be an enumerated type");
		}
		return Enum.ToObject(enumType, value);
	}
	#endregion

	#region Get Index from string
	public static int GetIndex<T>(string value) where T : struct, IConvertible {
		return GetIndex(typeof(T), value);
	}

	public static int GetIndex(Type enumType, string value) {
		if (!enumType.IsEnum) {
			throw new ArgumentException("T must be an enumerated type");
		}
		if (string.IsNullOrEmpty(value)) {
			throw new ArgumentException("Value is null or empty");
		}
		return (int)Enum.Parse(enumType, value);
	}
	#endregion
}